#ifndef __processpoll__
#define __processpoll__
using namespace std;
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
class channel // 先描述
{
public:
    channel(int rpipeid, int wpipeid, pid_t subid) : _rpipeid(rpipeid), _wpipeid(wpipeid), _subid(subid)
    {
    }
    pid_t getpid()
    {
        return _subid;
    }
    int getwpipe()
    {
        return _wpipeid;
    }
    int getrpipe()
    {
        return _rpipeid;
    }

private:
    int _rpipeid;
    int _wpipeid;
    pid_t _subid;
};

class channel_manager // 再组织
{
public:
    channel_manager() : find(0)
    {
    }
    void insertchannel(int rpipeid, int wpipeid, pid_t subid)
    {
        _channels.emplace_back(rpipeid, wpipeid, subid);
    }
    channel &select()
    {
        channel &tmp = _channels[find];
        find++;
        find %= _channels.size();
        return tmp;
    }
    void Close()
    {
        for(int i=0;i<_channels.size();i++)
        {
            close(_channels[i].getwpipe());
            waitpid(_channels[i].getpid(),nullptr,0);
        }
    }

private:
    vector<channel> _channels;
    int find;
};

class processpool // 进程池
{
public:
    processpool(int num) : process_num(num)
    {
        
    }
    bool create()
    {
        for (int i = 0; i < process_num; i++)
        {
            // 1.创建管道
            int pipeid[2] = {0};
            int n = pipe(pipeid);
            if (n < 0)
                return false;
            // 2.创建子进程
            pid_t subid = fork();
            if (subid < 0)
                return false;
            else if (subid == 0) // 子进程
            {
                close(pipeid[1]);
                cm.Close();
                while (1)
                {
                    int code = 0;
                    ssize_t n = read(pipeid[0], &code, sizeof(code));
                    if (n > 0)
                    {
                        if (n != sizeof(code))
                            continue;
                        cout << "子进程的pid:" << getpid() << "任务码:" << code << endl;
                    }
                    else if (n == 0)
                    {
                        cout << "子进程退出" << endl;
                        break;
                    }
                    else
                    {
                        cout << "读取错误" << endl;
                        break;
                    }
                }
                exit(0);
            }
            cm.insertchannel(pipeid[0], pipeid[1], subid); // 子进程队列中存放的都是父进程写的pipeid
            close(pipeid[0]);
        }
        return true;
    }
    void writework(int sendcode)
    {
        channel &aimch = cm.select();
        write(aimch.getwpipe(), &sendcode, sizeof(sendcode));
        cout << "选择的子进程是:---- " << aimch.getpid() << "任务码是: " << sendcode << endl;
    }
    void Close()
    {
        cm.Close();
    }
private:
    channel_manager cm;
    int process_num;
};
#endif
